#include <QDebug>
#include <mpd/client.h>
#include <mpd/song.h>
#include "mpdclient.h"

MPDClient::MPDClient() : isConnected(false)
{}

bool MPDClient::connection(QString address, int port, int timeout)
{
    conn = mpd_connection_new(address.toStdString().c_str(), port, timeout*1000);
    if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
        mpd_connection_free(conn);
        isConnected = false;
        return false;
    }
    connected();
    isConnected = true;
    return true;
}

MPDClient::status* MPDClient::getStatus()
{
    if(isConnected)
    {
        mpd_status *s = mpd_run_status(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return s;
    }
    return 0;
}

int MPDClient::position(mpd_status *s)
{
    if(isConnected)
    {
        int a;
        if (!s)
        {
            s = mpd_run_status(conn);
            if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
            {
                isConnected = false;
                mpd_connection_free(conn);
                connectionBroken();
                qDebug() << mpd_connection_get_error_message(conn);
                return -1;
            }
            a = mpd_status_get_elapsed_time(s);
            mpd_status_free(s);
        }
        else
            a = mpd_status_get_elapsed_time(s);
        return a;
    }
    return -1;
}

int MPDClient::totalTime(mpd_status *s)
{
    if(isConnected)
    {
        int a;
        if (!s)
        {
            s = mpd_run_status(conn);
            if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
            {
                isConnected = false;
                mpd_connection_free(conn);
                connectionBroken();
                qDebug() << mpd_connection_get_error_message(conn);
                return -1;
            }
            a = mpd_status_get_total_time(s);
            mpd_status_free(s);
        }
        else
            a = mpd_status_get_total_time(s);
        return a;
    }
    return -1;
}

void MPDClient::freeStatus(mpd_status *s)
{
    if(s)
        mpd_status_free(s);
}

MPDClient::~MPDClient()
{
    if(isConnected)
        mpd_connection_free(conn);
}

bool MPDClient::next()
{
    if(isConnected)
    {
        bool a = mpd_run_next(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return a;
    }
    return false;
}

bool MPDClient::stop()
{
    if(isConnected)
    {
        bool a = mpd_run_stop(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return a;
    }
    return false;
}

bool MPDClient::play()
{
    if(isConnected)
    {
        bool a = mpd_run_play(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return a;
    }
    return false;
}

bool MPDClient::pause()
{
    if(isConnected)
    {
        bool a = mpd_run_pause(conn, true);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return a;
    }
    return false;
}

bool MPDClient::prev()
{
    if(isConnected)
    {
        bool a = mpd_run_previous(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        return a;
    }
    return false;
}

bool MPDClient::isPlaying(mpd_status *s)
{
    if(isConnected)
    {
        bool ret;
        if (!s)
        {
            mpd_status *s = mpd_run_status(conn);
            if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
            {
                isConnected = false;
                mpd_connection_free(conn);
                connectionBroken();
                qDebug() << mpd_connection_get_error_message(conn);
                return false;
            }
            ret = (mpd_status_get_state(s) == MPD_STATE_PLAY);
            mpd_status_free(s);
        }
        else
            ret = (mpd_status_get_state(s) == MPD_STATE_PLAY);
        return ret;
    }
    return false;
}

bool MPDClient::isStoped(mpd_status *s)
{
    if(isConnected)
    {
        bool ret;
        if (!s)
        {
            mpd_status *s = mpd_run_status(conn);
            if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
            {
                isConnected = false;
                mpd_connection_free(conn);
                connectionBroken();
                qDebug() << mpd_connection_get_error_message(conn);
                return true;
            }
            ret = (mpd_status_get_state(s) == MPD_STATE_STOP);
            mpd_status_free(s);
        }
        else
            ret = (mpd_status_get_state(s) == MPD_STATE_STOP);
        return ret;
    }
    return true;
}

bool MPDClient::checkConnection()
{
    return isConnected;
}

MPDClient::song MPDClient::currentSong()
{
    MPDClient::song song_struct;
    if(isConnected)
    {
        mpd_song *a = mpd_run_current_song(conn);
        if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            isConnected = false;
            mpd_connection_free(conn);
            connectionBroken();
            qDebug() << mpd_connection_get_error_message(conn);
        }
        else
        {
            song_struct.album = mpd_song_get_tag(a, MPD_TAG_ALBUM,0);
            song_struct.artist = mpd_song_get_tag(a, MPD_TAG_ARTIST,0);
            song_struct.title = mpd_song_get_tag(a, MPD_TAG_TITLE,0);
            song_struct.track = mpd_song_get_tag(a, MPD_TAG_TRACK,0);
            song_struct.duration = mpd_song_get_duration(a);
        }
        mpd_song_free(a);
    }
    else
        song_struct.duration = -1;
    return song_struct;
}
